perm filename A.TEX[MF,DEK] blob
sn#783948 filedate 1985-01-29 generic text, type T, neo UTF8
\ansno2.1:
Point $5=(100,0)$ is closer than any of the others. \ (See
the diagram below.)
\ansno2.2:
\decreasehsize 15pc
\rightfig A2a (13pc x 5pc) ↑9pt
False. But they all do have the same $y$~coordinate.
\ansno2.3:
5 units to the {\sl left\/} of the reference point, and 15 units up.
\ansno2.4:
\restorehsize $(200,-60)$.
\ansno2.5:
$"top"\,"lft"\,z↓1=(0,b)$; \ $"top"\,z↓2=(a,b)$; \
$"top"\,"rt"\,z↓3=(2a-1,b)$; \ $"bot"\,"lft"\,z↓4=(0,0)$; \
$"bot"\,z↓5=(a,0)$; \ $"bot"\,"rt"\,z↓6=(2a-1,0)$.
Adjacent characters will be separated by exactly one column of white
pixels, if character is $2a$ pixels wide, because the right edge of
black pixels is specified here to have the $x$~coordinate $2a-1$.
\ansno2.6:
$"right"=(1,0)$; $"left"=(-1,0)$; $"down"=(0,-1)$; $"up"=(0,1)$.
\ansno2.7:
True; this is $(2,3)-(5,-2)$.
\ansno2.8:
$0[z↓1,z↓2]=z↓1$, because we move none of the way towards~$z↓2$;
similarly $1[z↓1,z↓2]$ simplifies to~$z↓2$, because we move all of the
way. If we keep going in the same direction until we've gone twice as far
as the distance from $z↓1$ to~$z↓2$, we get to $2[z↓1,z↓2]$. But if we
start at point~$z↓1$ and face~$z↓2$, then back up exactly half the distance
between them, we wind up at $(-.5)[z↓1,z↓2]$.
\ansno2.9:
(a)~True; both are equal to $z↓1+{1\over2}(z↓2-z↓1)$.
(b)~False, but close; the right-hand side should be
${2\over3}z↓1+{1\over3}z↓2$. (c)~True; both are equal to $(1-t)z↓1+tz↓2$.
\ansno2.10:
There are several reasons. (1)~The equations in a \MF\ program
should represent the programmer's intentions as directly as possible;
it's hard to understand those intentions if you are shown only
their ultimate consequences, since it's not easy to reconstruct algebraic
manipulations that have gone on behind the scenes. (2)~It's easier and
safer to let the computer do algebraic calculations, rather than
to do them by hand. (3)~If the specifications for $z↓1$ and $z↓5$ change,
the formula $\bigl({1\over2}[x↓1,x↓5],b\bigr)$
still gives a reasonable value for~$z↓3$. It's
almost always good to anticipate the need for subsequent modifications.\par
However, the stated formula for $z↓3$ isn't the only reasonable way to
proceed. We could, for example, give two equations
\begindisplay
$x↓3-x↓1=x↓5-x↓3$;\qquad $y↓3=b$;
\enddisplay
the first of these states that the horizontal distance from 1 to 3 is
the same as the horizontal distance from 3 to~5. We'll see later that
\MF\ is able to solve a wide variety of equations.
\ansno2.11:
The following four equations suffice to define the four
unknown quantities $x↓2$, $y↓2$, $x↓4$, and $y↓4$:
$z↓4-z↓2="whatever"\times"dir"\,20$;
${1\over2}[y↓2,y↓4]={2\over3}[y↓3,y↓1]$;
$z↓2="whatever"[z↓1,z↓3]$;
$z↓4="whatever"[z↓3,z↓5]$. ↑↑"whatever" ↑↑{dir}
\ansno3.1:
The direction at $z↓2$ is parallel to the line $z↓4\to z↓3$, but
the vector $z↓4-z↓3$ specifies a direction towards $z↓4$, which is
$180↑\circ$ different from the direction $z↓3-z↓4$ that was discussed in
the text. Thus, we have a difficult specification to meet, and \MF\ draws
a pretzel-shaped curve that loops around in a way that's too ugly to show
here. The first part of the path, from $z↓4$ to $z↓2$, is mirror symmetric
about the line~$z1\to z5$ that bisects $z↓4\to z↓2$, so it starts out in a
south-by-southwesterly direction; the second part is mirror symmetric about
the vertical line that bisects $z↓2\to z↓3$, so when the curve ends at~$z↓3$
it's traveling roughly northwest. The moral is: Don't specify a direction
that runs opposite to (i.e., is the negative of) the one you really want.
\ansno3.2:
@draw@ $z↓5\to z↓4\{z↓4-z↓2\}\to z↓1\to z↓3\to z↓6\{z↓2-z↓6\}
\to\cycle$.
\ansno4.1:
(a)~An ellipse $0.8\pt$ tall and $0.2\pt$ wide
(`$\,\vcenter{\hbox{\manual\nibc}}\,$');
\ (b)~A~circle of diameter $0.8\pt$ (rotation doesn't change a circle!);
\ (c)~same as~(a).
\ansno4.2:
Six individual points will be drawn, instead of lines or curves.
These points will be drawn with the current pen. However, for technical
reasons explained in Chapter~xx, the @draw@ command does its best work when it
is moving the pen; the pixels you get at the endpoints of curves are
not always what you would expect, especially at low resolutions. It is
usually best to say `↑@drawdot@' instead of `@draw@' when you are drawing
only ↑{one point}.
\ansno4.3:
True, for all of the pens discussed so far. But false in general,
since we will see later that pens might extend further upward than
downward; i.e., $t$~might be unequal to~$b$ in the equations for
"top" and "bot".
\ansno4.4:
$x↓2=x↓1$; $x↓3={1\over2}[x↓2,x↓4]$; $x↓4=x↓5$; $"bot"\,y↓1=-o$;
$"top"\,y↓2=h+o$; $y↓4=y↓2$; $y↓5=y↓1$; @draw@ $z↓1\to z↓2$;
@draw@ $z↓2\to z↓3$; @draw@ $z↓3\to z↓4$; @draw@ $z↓4\to z↓5$.
We will learn later that the four @draw@ commands can be replaced by
\begindisplay
@draw@ $z↓1\dashto z↓2\dashto z↓3\dashto z↓4\dashto z↓5$;
\enddisplay
in fact, this will make \MF\ run slightly faster. ↑↑{--}
\ansno4.5:
Either say `@fill@ $z↓5\to z↓4\to z↓1\to z↓3\to z↓6\to z↓5\to
\cycle$', which doubles point~$z↓5$ and abandons smoothness there,
or `@fill@ $z↓5\{\curl1\}\to z↓4\to z↓1\to z↓3\to z↓6\to
\{\curl1\}\cycle$'. In the latter case you can omit either one of
the ↑{curl} specifications, but not both.
\ansno4.6:
After the six original points have been defined, say
\begindisplay
@fill@ $z↓5\to z↓4\to z↓1\to z↓3\to z↓6\to\cycle$;\cr
$z↓0=(.8[x↓1,x↓2],.5[y↓1,y↓4])$;\cr
@for@ $k=1$ @upto@ 6: $z↓k'=.2[z↓k,z↓0]$; @endfor@\cr
@unfill@ $z↓5'\to z↓4'\to z↓1'\to z↓3'\to z↓6'\to\cycle$.\cr
\enddisplay
\ansno4.7:
${1\over2}\bigl["North",{1\over2}["North","West"]\bigr]=
{1\over2}\bigl[90,{1\over2}[90,180]\bigr]={1\over2}[90,135]=112.5$.
\ansno4.8:
$30↑\circ$, $60↑\circ$, $210↑\circ$, and $240↑\circ$. Since it's
possible to add or subtract $360↑\circ$ without changing the meaning,
the answers $-330↑\circ$, $-300↑\circ$, $-150↑\circ$, and $-120↑\circ$
are also correct.
\ansno4.9:
$z↓{1l}=(25,30)$, $z↓{1r}=(25,20)$.
\ansno4.10:
He said `@penstroke@
$z↓{1e}\{"up"\}\to z↓{2e}\{"left"\}\to z↓{3e}\{"down"\}
\to z↓{4e}\{"right"\}\to\cycle$'.
\ansno4.11:
We use angles ↑{perpendicular} to $(w,h)$ and $(w,-h)$ at the
diagonal endpoints:
\begindisplay
$x↓{1l}=x↓{4l}=0$;\cr
$x↓2=x↓5=.5w$;\cr
$x↓{3r}=x↓{6r}=w$;\cr
$y↓{1r}=y↓2=y↓{3l}=h$;\cr
$y↓{4r}=y↓5=y↓{6l}=0$;\cr
$z↓7=z↓8=.5[z↓1,z↓6]$;\cr
$z↓{1'}=.25[z↓1,z↓6]$; \ $z↓{6'}=.75[z↓1,z↓6]$;\cr
$theta↓1:=\angle(w,-h)+90$;\cr
$\penpos1(b,theta↓1)$; \ $\penpos6(b,theta↓1)$;\cr
$\penpos7(.6b,theta↓1)$;\cr
$\penpos{1'}(b,theta↓1)$; \ $\penpos{6'}(b,theta↓1)$;\cr
@penstroke@ $z↓{1e}\to z↓{1'e}\{z↓{6'}-z↓{1'}\}\to z↓{7e}\to
\{z↓{6'}-z↓{1'}\}z↓{6'e}\to z↓{6e}$;\cr
$z↓{3'}=.25[z↓3,z↓4]$; \ $z↓{4'}=.75[z↓3,z↓4]$;\cr
$theta↓3:=\angle(-w,-h)+90$;\cr
$\penpos3(b,theta↓3)$; \ $\penpos4(b,theta↓3)$;\cr
$\penpos8(.6b,theta↓3)$;\cr
$\penpos{3'}(b,theta↓3)$; \ $\penpos{4'}(b,theta↓3)$;\cr
@penstroke@ $z↓{3e}\to z↓{3'e}\{z↓{4'}-z↓{3'}\}\to z↓{8e}\to
\{z↓{4'}-z↓{3'}\}z↓{4'e}\to z↓{4e}$;\cr
$\penpos2(b,0)$; \ $\penpos5(b,0)$; \ @penstroke@ $z↓{2e}\to z↓{5e}$.\cr
\enddisplay
\ansno5.1:
The width is |0.8em#|, and an |em#| is 10 true points, so the
box will be exactly $8\pt$ wide in device-independent units. The
height will be $7\pt$. \ (And the depth below the baseline will be $0\pt$.)
\ansno5.2:
$8\times3.6=28.8$ rounds to the value $w=29$; similarly, $h=25$.
\ (And $d=0$.)
\ansno5.3:
It's merely necessary to supply the proper environment
by using @beginchar@, etc., and by defining the appropriate
stem widths. We shouldn't use the names "thin" and "thick", which appear
already in the program for~O, unless we want to adopt exactly the same
conventions in the~T. The following solution assumes that the
``winning'' stem width for~I is $0.9\pt$:
\begintt
bar#:=.8pt#; stem#:=.9pt#;
define_blacker_pixels(bar,stem);
beginchar("T",0.6em#,cap#,0); "The letter T";
penpos1(bar,70);
penpos2(bar,35);
penpos4(bar,35);
penpos5(bar,55);
x1=0; x2l=1/3[x1l,x5l]; x4l=2/3[x1l,x5l]; x5=w;
y1r=h; y2r=y4r=.2[y1r,y1]; y5l=.3[y1l,y1];
penpos6(stem,20); pentaper6(.1,0);
penpos3(x6r-x6l,0);
penpos7(stem,10);
x3=.5w; x6r=x3r; x7=x6;
y3=y2; y6=2/3h; y7=0;
penstroke z1e{curl infinity}..z2e..z4e..{curl infinity}z5e;
penstroke z3e..z6e{down}..z7e;
penlabels(1,2,3,4,5,6,7); endchar;
\endtt
\ansno5.4:
Here's one way, using variables like "thick" and "bar"
that have already been defined in the~O or in the~T of the
\rightfig A5a ({200\apspix} x 252\apspix) ↑-60pt
previous exercise:
\begintt
beginchar("S",5/9em#,cap#,0); "The letter S";
penpos1(bar,70); penpos2(bar,80);
penpos3(.5[bar,thick],200); penpos5(.5[bar,thick],210);
penpos6(bar,80); penpos7(.25[bar,thick],75);
pentaper2(.4,.6); pentaper6(.3,.5);
x1=x5; y1r=.94h+o;
x2=x4=x6=.5w; y2r=h+o; y4=.54h; y6l=-o;
x3r=.04em; y3=.5[y4,y2];
x5l=w-.03em; y5=.5[y4,y6];
.5[x7l,x7]=.04em; y7l=.1h-o;
path trial; trial=z3{down}..z4..{down}z5;
pair dz; dz=direction 1 of trial;
penpos4(thick,angle dz-90);
penstroke z1e..z2e{left}..z3e{down}
..z4e{dz}..z5e{down}..z6e{left}..z7e;
penlabels(1,2,3,4,5,6,7); endchar;
\endtt
Notice that the pen angle at point 4 has been found by letting \MF\
↑↑{direction} construct a ↑{trial path} through the center points,
then using the ↑{perpendicular} direction. The letters work reasonably
well at their true size: `{\manual\IOI\IOO} {\manual\IOI\IOS}
{\manual\IOI\IOS\IOI\IOS} {\manual\IOT\IOO\IOO}; {\manual\IOT\IOO\IOS\IOS}
{\manual\IOI\IOT}, {\manual\IOO\IOT\IOI\IOS}.'
\ansno5.5:
After an ``isolated expression,'' \MF\ thinks it is at the end of
a statement or command, so it expects to see a semicolon next. You should
type, e.g., `|I;|~|mode_setup|' to keep \MF\ happy.
\ansno5.6:
Yes.
\ansno6.1:
(a) No, the second token represents $1\over65536$. \ (A token has
the same meaning as~`|0|' ↑↑{zero} if and only if its decimal value
is strictly less than $2↑{-17}=.00000\,76293\,94531\,25$.) \ (b)~Yes; both
tokens represent $1\over65536$, because 1~is the nearest integer to both
$.00001\times65536=.65536$ and $0.00002\times65536=1.31072$. \ (c)~No,
|0.00003| represents $2\over65536$. \ (d)~Yes, they both mean ``↑{enormous
number} that needs to be reduced''; \MF\ complains in both
cases and substitutes the largest legal numeric token. \ (Rounding
4095.999999 to the nearest multiple of $1\over65536$ yields 4096,
which is too big.)
\ansno6.2:
\cstok{xx}, \cstok{3.1} (a numeric token), \cstok{.6} (another
numeric token), \cstok{..}, \cstok{[[}, \cstok{a}, \cstok{+-},
\cstok{bc\_d}, \cstok{e}, \cstok{]}, \cstok{]}, \chardef\"=`\"\cstok{\"a
\%\"} (a string token), \cstok{<\|>}, \cstok{(} (see rule~5), \cstok{(},
\cstok{\$}, \cstok{1} (a numeric token), \cstok{5} (likewise numeric),
\cstok{\"+-\"} (a string token), and \cstok{\"\"} (a string token that
denotes an empty sequence of characters).
All of these tokens are symbolic unless otherwise mentioned. \ (Notice that
four of the spaces and two of the periods were deleted by rule~1.
One way to verify that \MF\ finds precisely these tokens is to prepare a
test file that says `|isolated| |expression;|' on its first line and that
contains the stated text on its second line. Then respond to \MF's
error message by repeatedly typing `|1|', so that one token is deleted
at a time.)
\ansno6.3:
The statement is basically true but potentially misleading. You can
insert any number of spaces {\sl between\/} tokens without changing the
meaning of a program, but you cannot insert a space in the {\sl middle\/}
of any token without changing something. You can delete spaces between
tokens {\sl unless\/} that would ``glue'' two adjacent tokens together.
\ansno6.4:
False. It may seem that this new sort of numeric token would be
recognized only in cases where the period is not followed by a digit,
hence the period would be dropped anyway by rule~1. However, the new rule
would have disastrous consequences in a line like `|draw| |z1..z2|'!
\ansno7.1:
You can put a space between the subscripts, as in `|a1|~|5|'. \
(We'll see later that a ↑{backslash} acts as a null symbol,
hence `|a1\5|' is another solution.)
\ansno7.2:
No; |a[-1]| can't be accessed without using |[| and |]|. The
only other form of \<subscript> is \<numeric token>, which can't be
negative. \ (Well, strictly speaking, you could say `|let|~|?=[;|
|let|~|??=]|' and then refer to `|a?-1??|'; but that's cheating.)
\ansno7.3:
Assuming that `|+|' was still a spark when he said `|let|~|plus=+|',
he can't refer to the variable `|a.plus1|' unless he changes the meaning of
|plus| again to make it a~tag. \ (We will eventually learn a way to do this
without permanently clobbering |plus|, as follows: `↑|begingroup| ↑|save|
|plus;| |a.plus1| ↑|endgroup|'.)
\ansno7.4:
True. \ (But a \<suffix> is not always a \<variable>.)
\ansno7.5:
Yes, because it removes any existing value that $x$ may have
had, of whatever type; otherwise you couldn't safely use $x$ in a
numeric equation. It's wise to declare numeric variables when you're
not sure about their former status, and when you're sure that you don't
care what their previous value was. A numeric declaration together with a
comment also provides useful documentation. \ (Incidentally, `|numeric|~|x|'
doesn't affect other variables like `|x2|' or `|x.x|' that might be present.)
\ansno7.6:
(a)~The `|42|' is illegal because subscripts must be collective.
\ (b)~The `|24|' is illegal because a \<declared variable> must start with
a \<symbolic token>, not a numeric token. \ (c)~There's nothing wrong with
the consecutive commas; the second comma begins a \<declared variable>, so
it loses its former meaning and becomes a tag. Thus \MF\ tries to declare
the variable `|,t,path|'. However, `|path|' cannot appear in a suffix,
since it's a spark. \ (Yes, this is admittedly tricky. Computers follow rules.)
\ansno8.1:
|((z1+z2)..((z3/4)*5))..(z6-(7*(8z9)))|.
\ansno8.2:
The fraction |100/3| is evaluated first (because such divisions
take precedence); the rounding error in this fraction is then magnified by~100.
\ansno8.3:
A |sqrt| takes precedence over any operation with two operands, hence
the machine computes `|(sqrt|~|2)**2|'; \MF\ was somewhat lucky that the
answer turned out to be exactly~2. \ (The |sqrt| operation computes the
nearest multiple of $1\over65536$, and the rounding error in this quantity
is magnified when it is squared. If you try |sqrt|~|3**2|, you'll get
|3.00002|; also |sqrt|~|2**4| turns out to be |4.00002|.) \ Incidentally,
the ↑|**| operation of plain \MF\ has the same precedence as |*| and~|/|;
hence `|x*y**2|' means the same as `|(x*y)**2|', and `|-x**2|' means
`|(-x)**2|', contrary to the conventions of {\eightrm ↑{FORTRAN}}.
\ansno8.4:
Since `↑@or@' has stronger precedence than `$<$' or `$>$', ↑↑|<| ↑↑|>|
\MF\thinspace\ tries to evaluate this expression by putting things in
parentheses as follows: `$(0>(1\mathbin{\bf or}a))<a$'. Now
`$1\mathbin{\bf or}a$' makes no sense, because `@or@' operates only on
booleans; in such cases \MF\ uses the right operand~`$a$' as the result. Then
`$\mkern1mu0>a$' is indeterminate because $a$~is unknown; \MF\ treats this as
false. Finally `${\rm false}<a$' is another illegal combination of types.
\ansno8.5:
The token `|++-|' is undefined, so it is a tag; therefore
|++-7| is a subscripted variable, which was multiplied by zero.
\ansno8.6:
The associative law is valid for exact computations, but not
for rounded computations. For example, it fails even in the case of
multiplication, since $(.1\ast.1)\ast10=0.09995$ while $.1\ast(.1\ast10)=.1$
when products are rounded to the nearest multiples of $1\over65536$.
However, this observation doesn't quite explain the stated example, which
would have yielded 7 in all cases if \MF\ had computed $2\pyth+4$ with
full accuracy! The closest approximation to $\sqrt{20}$ is ↑↑{accuracy}
$4{30942\over65536}$, but $2\pyth+4$ turns out to be $4{30941\over65536}$
instead. \MF\ computes the absolutely best possible approximations to the
true answers when it does multiplications, divisions, and square roots,
but not when it does Pythagorean operations.
\ansno8.7:
It's impossible to make an expression from `\<numeric token>
\<numeric token>', because the rule for \<scalar multiplication operator>
specifically prohibits this. \MF\ will recognize the first `|2|' as
a \<numeric primary>, which is ultimately regarded as a \<numeric
expression>; the other `|2|' will probably be an extra token that is
flushed away after an error message has been given.
\ansno8.8:
\<string primary>\is\<string variable>\parbreak
\qquad\alt\<string token>\parbreak
\def\\#1{\thinspace{\tt#1}\thinspace}%
\qquad\alt\\(\<string expression>\\)\parbreak
\qquad\alt\\{substring}\<pair expression>\\{of}\<string primary>\parbreak
\<string secondary>\is\<string primary>\parbreak
\<string tertiary>\is\<string secondary>\parbreak
\<string expression>\is\<string tertiary>\parbreak
\qquad\alt\<string expression>\\{\char`\&}\<string tertiary>\par
\medskip\noindent
(The full syntax in Chapter~xx includes several more varieties of
\<string primary> that haven't been hinted at yet.)
\ansno9.1:
(a)~Point 1 should lie nine pixels to the left of point~7,
considering horizontal positions only; no information is given about the
vertical positions $y↓1$ or $y↓7$. \ (b)~Point~7 should sit directly
above or below point~4, and its distance up from the baseline should be
halfway between that of points 4 and~5. \ (c)~The left edge of the
currently-picked-up pen, when that pen is centered at point~21, should be
one pixel to the right of its right edge when at point~20. \ (Thus there
should be one clear pixel of white space between the images of the
pen at points 20 and~21.)
\ansno9.2:
(a) $y↓{13}=-y↓{11}$ (or $-y↓{13}=y↓{11}$, or $y↓{13}+y↓{11}=0$).
\ (b)~$z↓{10}=z↓{12}+("mm",-1)$. \ (c)~$z↓{43}={1\over3}[(0,h),(w,-d)]$.
\ansno9.3:
(a) $z↓1=z↓2=z↓3=(w,h)$; $z↓4=z↓5=z↓6=(0,0)$.
\ (b)~$z↓1=z↓6=(.5w,.5h)$; $z↓2=(.75w,.75h)$; $z↓3=(w,h)$;
$z↓4=(0,0)$; $z↓5=(.25w,.25h)$.
\ansno9.4:
$z="whatever"[z↓1,z↓2]$; $z="whatever"[z↓3,z↓4]$. \ (Incidentally,
it's interesting to watch this computation in action. Run \MF\ with
|\tracingequations:=|\allowbreak|tracingonline:=1| and say, for example,
\begintt
z=whatever[(1,5),(8,19)]; z=whatever[(0,17),(6,1)];
\endtt
the solution appears as if by magic.
If you use |alpha| and |beta| in place of the whatevers, the machine will
also calculate values for "alpha" and "beta".)
\ansno9.5:
$z="whatever"[z↓1,z↓2]$; $z-z↓3="whatever"\ast(z↓5-z↓4)$.
\ansno9.6:
$z↓{11}-z↓{12}="whatever"\ast(z↓{13}-z↓{14})$ ↑{rotated} 90,
assuming that $z↓{13}-z↓{14}$ is known. \ (It's also possible to say
`$(z↓{11}-z↓{12})\mathbin{\rm dotprod} (z↓{13}-z↓{14})=0$', ↑↑{dotprod}
although this risks overflow if the coordinates are large.)
\ansno9.7:
One solution constructs the point $z↓4$ on $z↓2\to z↓3$ such
that $z↓4\to z↓1$ is perpendicular to $z↓2\to z↓3$, using ideas like
those in the previous two exercises: `$z↓4="whatever"[z↓2,z↓3]$;
$z↓4-z↓1="whatever"\ast(z↓3-z↓2)$ rotated 90'. Then the requested distance
↑↑{abs} ↑↑{ypart}
is $length(z↓4-z↓1)$. But there's a slicker solution: Just calculate
$$\hbox{abs ypart$((z↓1-z↓2)\mathbin{\rm rotated}-angle(z↓3-z↓2))$.}$$
\ansno9.8:
It would be nice to say simply `$z="whatever"[z↓2,z↓3]$' and
then to be able to say either `length$(z-z↓1)=l$' or `$z-z↓1=(l,0)$ rotated "whatever"';
but neither of the second equations is legal. \ (Indeed, there couldn't
possibly be a legal solution that has this general flavor, because any
such solution would determine a unique $z$, while there are two points to
be determined.) \ The best way seems to be to compute $z↓4$ as in the
previous exercise, ↑↑{pythagorean subtraction} and then to let
$v=(l\mathbin{+{-}+}\mathop{\rm length} (z↓4-z↓1))\ast\mathop{\rm
unitvector}(z↓3-z↓2)$; ↑↑{unitvector} ↑↑{length}
the desired points are then $z↓4+v$ and $z↓4-v$.
\ansno9.9:
Such an equation tells us nothing new about $a$ or $b$. Indeed,
each use of "whatever" introduces a new independent variable, and
each new independent variable ``uses up'' one equation, since we need
$n$ equations to determine the values of $n$~unknowns. On the other hand
an equation between pairs counts as two equations; so there's a net
gain of one, when "whatever" appears in an equation between pairs.
\ansno10.1:
Yes, but it must be done in two steps: `@numeric@ "newcode";
$"newcode"="code"+1$; @numeric@ "code"; $"code"="newcode"$'.
\ansno10.2:
The assignment `$x↓3:=\null$↑"whatever"' does exactly what you want.
\ansno10.3:
The result shows that $s↓1=s↓3=s↓4$ and $s↓2=s↓5=s↓6$ now:
\begintt
s[]=unknown string
s1=unknown string s3
s2=unknown string s6
s3=unknown string s4
s4=unknown string s1
s5=unknown string s2
s6=unknown string s5
\endtt
(The assignment $s↓2:=s↓5$ broke $s↓2$'s former relationship with $s↓1$,
$s↓3$, and $s↓4$.)
\ansno10.4:
The results are
\begindisplay
|## a=1|\cr
|## a=b+1|&(after the first assignment)\cr
|## b=0.5a-0.5|&(after the second assignment)\cr
|### -1.5a=-%CAPSULEnnnn-0.5|&(after the third assignment)\cr
|>> a|&(after `@show@'; variable $a$ is independent)\cr
|>> 0.33333a-0.33333|&(this is the final value of $b$)\cr
\enddisplay
↑↑|CAPSULE| Let $a↓k$ denote the value of $a$ after $k$ assignments were made.
Thus, $a↓0=1$, and $a↓1$ was dependent on the independent variable~$b$.
Then $a↓1$ was discarded and $b$ became dependent on the independent
variable~$a↓2$. The right-hand side of the third assignment was
therefore $a↓2+b$. At the time $a↓2$ was about to be discarded, \MF\
had two dependencies $b=0.5a↓2-0.5$ and $\kappa=1.5a↓2-0.5$, where
$\kappa$ was a nameless ``↑{capsule}'' inside of the computer, representing
the new value to be assigned. Since $\kappa$ had a higher coefficient
of dependency than~$b$, \MF\ chose to make $\kappa$ an independent variable,
after which $-1.5a↓2$ was replaced by $-\kappa-0.5$ in all dependencies; hence
$b$ was equal to $0.33333\kappa-0.33333$. After the third
assignment was finished, $\kappa$ disappeared and $a↓3$ became independent
in its place. \ (There's a 50-50 chance that the line `|##| |a=%CAPSULEnnnn|'
was also printed after the third assignment; this means that $a$ was
temporarily dependent on $\kappa$, before $\kappa$ was discarded. If
the equation $a=\kappa$ happened to make $\kappa$ dependent on~$a$, rather
than vice versa, no ↑↑{hash hash} `|##|' line was printed; such lines are
omitted when a capsule or part of a capsule has been made dependent, unless
you have made ↑"tracingcapsules"$\null>0$.)
\ansno11.1:
Almost, but not quite. The values of standard dimension variables
like "pt" and "mm" will be identical in both setups, as will the values of
ad~hoc dimension variables like "em" and "xheight". But pen-oriented
dimensions that are defined via @define\_blacker\_pixels@ will be slightly
different, because "cheapo" mode has $"blacker"=0.65$ while "luxo" mode
has $"blacker"=0.1$ (since the "luxo" printer has different physical
characteristics). Similarly, @define\_corrected\_pixels@ (which we are
just about to discuss) will produce slightly different results in the two
given modes.
\ansno11.2:
Increasing $"ht"\0$ would make the letter shape and the bounding
box taller; increasing $"xgap"\0$ would move point~5 to the left, thereby
making the middle bar shorter; increasing $u\0$ would make the shape and
its bounding box wider; increasing $s\0$ would widen the bounding box
at both sides without changing the letter shape; increasing $o\0$ would
move points 4,~5, and~6 to the right; increasing $"px"\0$ would make
the pen thicker (preserving the top edge of the upper bar, the bottom
edge of the lower bar, and the center of the middle bar and the stem).
\ansno11.3:
The only possible surprise is the position of $y↓1$,
which should match similar details in the `{\manual h}'
and the~`\kern1pt{\manual j}\kern1pt' of Chapter~4:
\begintt
beginchar("F",14*u#+2s#,ht#,0); pickup logo_pen;
x1=x2=x3=leftstemloc; x4=w-x1+o; x5=x4-xgap;
y2=y5; y3=y4; bot y1=-o; top y3=h; y2=barheight;
draw z1--z3--z4; draw z2--z5;
labels(1,2,3,4,5); endchar;
\endtt
\ansno11.4:
The quantity called "ss" in Chapter~4 is now "leftstemloc".
\begintt
beginchar("M",18*u#+2s#,ht#,0); pickup logo_pen;
x1=x2=leftstemloc; x4=x5=w-x1; x3=w-x3;
y1=y5; y2=y4; bot y1=-o; top y2=h+o; bot y3=ygap;
draw z1--z2--z3--z4--z5;
labels(1,2,3,4,5); endchar;|smallskip
beginchar("T",13*u#+2s#,ht#,0); pickup logo_pen;
lft x1=0; x2=w-x1; x3=x4=.5w;
y1=y2=y3; top y1=h; bot y4=-o;
draw z1--z2; draw z3--z4;
labels(1,2,3,4); endchar;
\endtt
\ansno11.5:
`{\manual nmnkjmnihinj}'; possibly also `{\manual hijklmmjnmji}'.
\ansno11.6:
Delete the line of |logo.mf| that defines |barheight#|, and
insert that line into each of the driver files |logo10.mf|, |logo9.mf|,
|logo8.mf|. Then other bar-line heights are possible by providing new
driver files; another degree of ``meta-ness'' has therefore been added
to the meta-font.
\ansno12.1:
The changes are straightforward, except for the italic correction
(for which a rough estimate like the one shown here is good enough):
\begindisplay
|"Right parenthesis"|;\cr
@numeric@ $"ht"\0,"dp"\0$; $"ht"\0="hheight"\0+"border"\0$;
$.5["ht"\0,-"dp"\0]="axis"\0$;\cr
@beginchar@(|")"|$,7u\0,"ht"\0,"dp"\0)$;
\ @italcorr@ $"axis"\0\ast"slant"-u\0$;\cr
@pickup@ "tinypen"; \ $\penpos1("hair"-"tiny",0)$;\cr
$\penpos2(.75["thin","thick"]-"tiny",0)$; \ $\penpos3("hair"-"tiny",0)$;\cr
$\mathop{"lft"}x↓{1l}=\mathop{"lft"}x↓{3l}=u$; \
$\mathop{"rt"}x↓{2r}=x↓1+4u$; \
$\mathop{"top"}y↓1=h$; \
$y↓2=.5[y↓1,y↓3]="axis"$;\cr
@filldraw@ $z↓{1l}\{\curl4\}\to z↓{2l}\to\{\curl4\}z↓{3l}\dashto$\cr
\qquad $z↓{3r}\{\curl4\}\to z↓{2r}\to\{\curl4\}z↓{1r}\dashto\cycle$;\cr
@penlabels@$(1,2,3)$; \ @endchar@;\cr
\enddisplay
We will see in Chapter xx that it's possible to guarantee perfect symmetry
between left and right parentheses by using picture transformations.
\ansno12.2:
When horizontal lines are being typeset, \TeX\ keeps track of the
maximum height and maximum depth of all boxes on the line; this determines
whether or not extra space is needed between baselines. The height and depth
are also used to position an accent above or below a character, and to
place symbols in mathematical formulas. Sometimes
boxes are also stacked~up vertically, in which case their heights and depths
are just as important as their widths are for horizontal setting.
\ansno13.1:
$(4,4)$, $(4,5)$, $(5,5)$, $(5,4)$. \ (Therefore the command
\begindisplay
@unfill@ $(4,4)\dashto(4,5)\dashto(5,5)\dashto(5,4)\dashto\cycle$
\enddisplay
will decrease the value of this pixel by 1.)
\ansno13.2:
The result would be exactly the same; @fill@ and @unfill@ commands
can be given in any order. \ (After an initial @unfill@ command, some
pixel values will be $-1$, the others will be zero.)
\ansno13.3:
@unfill@ $(4,1)\dashto(4,8)\dashto(5,8)\dashto(5,1)\dashto\cycle$.
\ansno13.4:
Here are two of the many solutions:
\begindisplay
@fill@ $(0,3)\dashto(9,3)\dashto(9,6)\dashto(6,6)\dashto(6,9)\dashto$\cr
\indent $(3,9)\dashto(3,0)\dashto(6,0)\dashto(6,6)\dashto(0,6)\dashto\cycle$;\cr
@fill@ $(0,3)\dashto(9,3)\dashto(9,6)\dashto(0,6)\dashto(0,3)\dashto$\cr
\indent $(3,3)\dashto(3,0)\dashto(6,0)\dashto(6,9)\dashto(3,9)\dashto
(3,3)\dashto\cycle$.\cr
\enddisplay
(It turns out that {\sl any\/} pixel pattern can be obtained by a single,
sufficiently hairy @fill@ command. But unnatural commands are usually also
inefficient and unreadable.)
\ansno13.5:
The value of the enclosed pixel is increased by 2. \ (We'll see later
that there's a simpler way to do this.)
\ansno13.6:
True; $j-k=l-m$, since $k+l=j+m$. \ (What comes up must go down.)
\ansno13.7:
The tricky part is to remember that `@erase@ @draw@ $z↓i\dashto z↓j$'
will erase pixels near $z↓i$ and $z↓j$. Therefore if $z↓3\dashto z↓4$ is
drawn before $z↓4\dashto z↓2$, we can't erase $z↓4\dashto z↓2$ without losing
some of $z↓3\dashto z↓4$; it's necessary to erase only part of one line.
One way to solve the problem is to do the following, after defining the
points and picking up the pen as before:
\begindisplay
@draw@ $z↓3\dashto z↓4$; \ @draw@ $z↓5\dashto z↓6$;\cr
↑@cullit@; \ \pickup @pencircle@ scaled $1.6"pt"$;\cr
↑@undraw@ $z↓7\dashto {1\over2}[z↓7,z↓5]$; \
@undraw@ $z↓2\dashto {1\over2}[z↓2,z↓4]$;\cr
@cullit@; \ \pickup @pencircle@ scaled $.4"pt"$;\cr
@draw@ $z↓3\dashto z↓1\dashto z↓2\dashto z↓4$; \
@draw@ $z↓5\dashto z↓7\dashto z↓8\dashto z↓6$;\cr
@for@ $k=1$ @upto@ 4: \ @draw@ $z↓k\dashto z↓{k+4}$; \ @endfor@.\cr
\enddisplay
(Note that it would not be quite enough to erase only from $z↓7$ to
${1\over3}[z↓7,z↓5]$!)\par
It's also possible to solve this problem without partial erasing, if we
use additional features of \MF\ that haven't been explained yet. Let's
consider only the job of drawing $z↓7\dashto z↓5\dashto z↓6$ and
$z↓3\dashto z↓4\dashto z↓2$, since the other eight lines can easily be
added later. Alternative Solution~1 uses picture operations:
\begindisplay
@pen@ "eraser"; \ $"eraser"=@pencircle@$ scaled $1.6"pt"$;\cr
@draw@ $z↓3\dashto z↓4$; \
@erase@ @draw@ $z↓7\dashto z↓5$ ↑@withpen@ "eraser"; \
@draw@ $z↓7\dashto z↓5$;\cr
@picture@ "savedpicture"; \ $"savedpicture"="currentpicture"$; \ ↑@clearit@;\cr
@draw@ $z↓6\dashto z↓5$; \
@erase@ @draw@ $z↓2\dashto z↓4$ ↑@withpen@ "eraser"; \
@draw@ $z↓2\dashto z↓4$;\cr
↑@addto@ "currentpicture" @also@ "savedpicture".\cr
\enddisplay
Alternative Solution 2 is trickier, but still instructive; it uses
`↑@withweight@' options and the fact that @draw@ does not increase any
pixel values by more than the stated weight when the path is a straight
line:
\begindisplay
@draw@ $z↓3\dashto z↓4$; \
↑@undraw@ $z↓7\dashto z↓5$ @withpen@ "eraser";\cr
@draw@ $z↓7\dashto z↓5$ @withweight@ 2; \
↑@cullit@ @withweight@ 2;\cr
@draw@ $z↓6\dashto z↓5$; \
↑@undraw@ $z↓2\dashto z↓4$ @withpen@ "eraser";\cr
@draw@ $z↓2\dashto z↓4$ @withweight@ 2;\cr
\enddisplay
(These alternative solutions were suggested by Bruce ↑{Leban}.)
\ansno13.8:
Here's an analog of the first solution to the previous
exercise:
\begindisplay
@beginchar@(|"*"|$,10"pt"\0,7"pt"\0,2"pt"\0)$;\cr
@pair@ "center"; \dots \<as in the hint>\cr
\pickup @pencircle@ scaled $.4"pt"$; \ @draw@ "star";\cr
@cullit@; \ \pickup @pencircle@ scaled $1.6"pt"$;\cr
@for@ $k=0$ @upto@ 4: \ @undraw@ subpath$(k+.55,k+.7)$ @of@ "star"; \ @endfor@\cr
@cullit@; \ \pickup @pencircle@ scaled $.4"pt"$;\cr
@for@ $k=0$ @upto@ 4: \ @draw@ subpath$(k+.47,k+.8)$ @of@ "star"; \ @endfor@\cr
@labels@(0,1,2,3,4); \ @endchar@.\cr
\enddisplay
However, as in the previous case, there's an Alternate Solution~1
by Bruce ↑{Leban} that is preferable because it doesn't depend
on magic constants like .55 and~.47:
\begindisplay
@beginchar@ $\ldots$ \<as above> $\ldots$ scaled $.4"pt"$;\cr
@picture@ "savedpicture"; \ $"savedpicture"="nullpicture"$;\cr
@pen@ "eraser"; \ $"eraser":=@pencircle@$ scaled $1.6"pt"$;\cr
@for@ $k=0$ @upto@ 4:\cr
\indent @draw@ subpath$(k,k+1)$ @of@ "star"; @cullit@;\cr
\indent @undraw@ subpath$(k+3,k+4)$ @of@ "star" @withpen@ "eraser"; @cullit@;\cr
\indent @addto@ "savedpicture" @also@ "currentpicture"; @clearit@; @endfor@\cr
$"currentpicture":="savedpicture"$; \ @labels@(0,1,2,3,4); \ @endchar@.\cr
\enddisplay
\ansno13.9:
It increases pixel values by 1 in the five lobes of the star, and by~2
in the central pentagon-like region.
\ansno13.10:
@def@ @overdraw@ @expr@ $c$ = @erase@ @fill@ $c$; @draw@ $c$ @enddef@.
\ansno13.11:
First we need to generalize the ↑@overdraw@ macro of the previous
exercise so that it applies to arbitrary cycles~$c$, even those that are
self-intersecting:
\begindisplay
@def@ @overdraw@ @expr@ $c$ = ↑@begingroup@\cr
\indent@picture@ "region"; $"region":="nullpicture"$;\cr
\indent↑@interim@ $"turningcheck":=0$; ↑@addto@ "region" @contour@ $c$;\cr
\indent↑@cull@ "region" @dropping@ $(0,0)$;\cr
\indent↑@cullit@; @addto@ "currentpicture" ↑@also@ $-"region"$; @cullit@;\cr
\indent@draw@ $c$ ↑@endgroup@ @enddef@;\cr
\enddisplay
(This code uses operations defined later in this chapter; it erases the
"region" of pixels that would be made nonzero by the command `@fill@~$c$'.)
\ The watchband is now formed by overdrawing its links, one at a time,
doing first the ones that are underneath:
\begindisplay
@beginchar@$("M",1.25"in"\0,.5"in"\0,0)$;\cr
\pickup @pencircle@ scaled .4"pt";\cr
$z↓1=(20,-13)$; \ $z↓2=(30,-6)$; \ $z↓3=(20,1)$; $z↓4=(4,-7)$;\cr
\indent $z↓5=(-12,-13)$; \ $z↓6=(-24,-4)$; \ $z↓7=(-15,6)$;\cr
@path@ $M$; $M=("origin"\to z1\to z2\to z3\to z4\to z5\to z6\to z7\to$\cr
\indent$"origin"\to -z7\to -z6\to -z5\to -z4\to -z3\to -z2\to -z1\to\cycle)$\cr
↑↑"origin" \indent\indent scaled $(h/26)$ shifted $(.5w,.5h)$;\cr
@def@ @link@(@expr@ $n$) =\cr
\indent @overdraw@ subpath ${1\over3}(n,n+1)$ of $M\;\dashto$\cr
\indent\indent subpath ${1\over3}(n+25,n+24)$ of $M\;\dashto\;\cycle\;$
@enddef@;\cr
@for@ $k=1$ @upto@ 12: @link@$(k+11)$; @link@$(12-k)$; @endfor@
@endchar@;\cr
\enddisplay
\ansno13.12:
The pixel pattern $\pixpat1121$ is culled to $\pixpat1111\,$,
and \MF\ needs to sort the edges as it does this; so the result is simply
\begintt
row 1: || 0+ 2-
row 0: || 0+ 2-
\endtt
\ansno13.13:
The pixel pattern is $\pixpat1121+\pixpat1121+\pixpat1112-\pixpat2111
=\pixpat1243$ before the final rotation, with the reference point at the
lower left corner of the~4; after rotation it is $\pixpat2314\,$, with the
reference point at the lower {\sl right\/} corner of the~4. Rotation causes
\MF\ to sort the edges, but the transition values per edge are never
more than $\pm3$. You weren't expected to know about this limit of $\pm3$,
but it accounts for what is actually reported:
\begintt
row 1: || -2++ -1+ 0---
row 0: || -2+ -1+++ 0--- 0-
\endtt
\ansno13.14:
`|V| |scaled-1|' should be the same as `|V| |rotated| |180|',
because transformations apply to coordinates rather than to pixel values.
\ (Note, incidentally, that the reflections `|V|~↑|xscaled-1|' and
`|V|~↑|yscaled-1|' both work, and that `|V|~|scaled-1|' is the same as
`|V|~|xscaled-1| |yscaled-1|'.)
\ansno13.15:
The result is the same as `|V| |shifted| |(2,3)|'; the coordinates
of a shift are rounded to the nearest integers when a picture is being shifted.
\ansno13.16:
\MF\ is currently executing instructions after having read
as far as line~5 of the file |expr.mf|.
\ansno13.17:
The pixel values of "currentpicture" become 1 if they were $\pm1$,
otherwise they become~0.
\ansno13.18:
(a) @addto@ $V↓1$ @also@ $V↓2$; @cull@ $V↓1$
@keeping@ $(2,2)$. \ (b) Same, but cull keeping $(1,2)$.
\ (c)~Same, but cull keeping $(1,1)$.
\ansno13.19:
Subtract one from the other, and cull the result dropping $(0,0)$;
then test if the total weight is zero.
\ansno13.20:
(a)~Same as `@draw@ $p$', but using $q$ instead of the currently-picked-up
pen. \ (b)~Same effect as `@draw@~$p$; @draw@~$p$; @draw@~$p$' (but faster).
\ (c)~Same as `@draw@~$p$ @withweight@~$w$', because @undraw@'s
`@withweight@~$-1$' is overridden.
\ (d)~Same as `@unfilldraw@~$c$; @unfilldraw@~$c$',
but using $q$ instead of "currentpen".
\ (e)~Same as `@erase@ @filldraw@~$c$', because the `@withweight@~2' is
overridden. \kern-.7pt
\ (f)~Same effect as `@cullit@; @addto@ "currentpicture" @also@ "currentpicture"'
(but faster).
\ [Cases (a), (b), (d), and~(f) are useful; but---alas, alack!---cases (c)
and~(e) are counter-intuitive.]
\ansno13.21:
@def@ @safefill@ @expr@ $c$ $=$
↑@begingroup@ ↑@save@ "region";\parbreak
@picture@ "region"; "region"="nullpicture";\parbreak
↑@interim@ $"turningcheck":=1$; \ @addto@ "region" @contour@ $c$;\parbreak
@cull@ "region" @dropping@ $(0,0)$;
\ @addto@ "currentpicture" @also@ "region";\parbreak
↑@endgroup@ @enddef@.